package com.kili.file.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

/**
 * SpringContextHolder
 * <p>
 * The BeanFactory that loads the bean(SpringContextHolder) can be obtained during the process of loading the bean.
 *
 * @author Gordon
 * @version 2019/3/30
 */
@Component
@Slf4j
public class SpringContextHolder implements BeanFactoryAware {

    /**
     * Global application object
     */
    public static DefaultListableBeanFactory applicationContext;


    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        applicationContext = (DefaultListableBeanFactory) beanFactory;
    }

    public static <T> T getBean(Class<T> requiredType) {
        assertApplicationContext();
        log.info("Non-injected annotation to get an object" +
                        " instance for SpringContextHolder ," +
                        "param type is {}\t",
                requiredType.getName());
        return applicationContext.getBean(requiredType);
    }

    public static Object getBean(String beanName) {
        assertApplicationContext();
        return applicationContext.getBean(beanName);
    }


    private static void assertApplicationContext() {
        if (SpringContextHolder.applicationContext == null) {
            log.warn("System inject catch  applicationContext is {}" +
                            " when application is doing setup",
                    applicationContext);

            throw new RuntimeException("The Application Context property is null," +
                    " please check if SpringContextHolder is injected!");
        }
    }
//    public static void registerSpecialAnonymousBean(Class classType, String className) {
//        RootBeanDefinition helloBean = new RootBeanDefinition(classType);
//        applicationContext.registerBeanDefinition(className, helloBean);
//    }
//
//    public static void removeSpecialAnonymousBean(String className) {
//        applicationContext.removeBeanDefinition(className);
//    }


}
